#include "threadpool.h"
#include "threadworker.h"

// Inits thread pool
void ThreadPool::init()
{
    for (int i = 0; i < m_threads.size(); ++i)
    {
        m_threads.at(i) = std::thread(ThreadWorker(this, i)); // 分配工作线程
    }
}
// Waits until threads finish their current task and shutdowns the pool
void ThreadPool::shutdown()
{
    m_shutdown = true;
    m_conditional_lock.notify_all(); // 通知，唤醒所有工作线程

    for (int i = 0; i < m_threads.size(); ++i)
    {
        if (m_threads.at(i).joinable()) // 判断线程是否在等待
        {
            m_threads.at(i).join(); // 将线程加入到等待队列
        }
    }
}
template <typename F, typename... Args>
auto ThreadPool::submit(F &&f, Args &&...args) -> std::future<decltype(f(args...))>
{
    // Create a function with bounded parameter ready to execute
    std::function<decltype(f(args...))()> func = std::bind(std::forward<F>(f), std::forward<Args>(args)...); // 连接函数和参数定义，特殊函数类型，避免左右值错误
    // Encapsulate it into a shared pointer in order to be able to copy construct
    auto task_ptr = std::make_shared<std::packaged_task<decltype(f(args...))()>>(func);

    // Warp packaged task into void function
    std::function<void()> warpper_func = [task_ptr](){
        (*task_ptr)();
    };
    // 队列通用安全封包函数，并压入安全队列
    m_queue.enqueue(warpper_func);
    // 唤醒一个等待中的线程
    m_conditional_lock.notify_one();
    // 返回先前注册的任务指针
    return task_ptr->get_future();
}


